#include "Lkqueue.h"


/*

InitQueue:初始化一个队列
返回值:返回创建好的队列的地址
*/
LkQueue *InitQueue()
{
    //分配链表队列空间
    LkQueue *q = (LkQueue *)malloc(sizeof(LkQueue));
    //空间初始化
    q->front = 0;
    q->rear = 0;
    q->num = 0;
    return q;
}

/*
DestoryQueue:销毁一个队列
@q:你要销毁的队列的地址
返回值:无
*/
void DestoryQueue(LkQueue *q)
{
    if(q)
    {
        ClearQueue(q);
        free(q);
    }
}

/*
ClearQueue :清空一个队列(把队列中的数据元素都清空)
@q:你要清空的队列的地址
返回值:无
*/
void ClearQueue(LkQueue *q)
{
    if(q == NULL || q->front ==NULL)
    {
        return;
    }
    while(!QueueIsEmpty(q))
    {
        DeQueue(q);
    }
}


/*
QueueIsEmqty:判断队列是否为空(是否存在用户数据)
@q:你要操作的队列的地址
返回值:
    返回true表示队列为空
    返回false表示队列不为空
*/
bool QueueIsEmpty(LkQueue *q)
{
    return q == NULL || q->num == 0;
}


/*
QueueSize:获取队列的大小(用户元素的个数)
@q:你要操作的队列的地址
返回值:
返回队列中当前的元素个数
*/
int QueueSize(LkQueue *q)
{
     return q == NULL? 0:q->num;
}

/*
GetHead:获取队头元素(下一次出队的元素),但是不出队列
@q:你要操作的队列的地址
@v:指针,指向一块可用的空间,用来保存队头数据的值
返回值:
    返回true表示获取成功
    返回false表示获取失败
*/
bool GetHead(LkQueue *q,Datatype *v)
{
    if(QueueIsEmpty(q))
    {
        return false;
    }
    //把对头元素存放到
    //Node *pre = q->front;
    *v = q->front->data;
    return true;
}

/*
EnQueue(qush):入队列,把一个用户数据存放到队列中去(放到队尾)
@q:你要操作的队列的地址
@value:你要入队的数据
返回值:
    返回true表示入队成功
    返回false表示入队失败
*/
bool EnQueue(LkQueue *q,Datatype value)
{
    //分配一个节点空间
    Node *p = (Node *)malloc(sizeof(Node));
    p->data = value;
    p->next = NULL;
    p->prev = NULL;
    if(q->front == NULL)
    {         
        q->front = q->rear = p;
        q->num++;
    }
    else
    {
        q->rear->next = p;
        p->next = q->rear;
        q->rear = p;
        q->num++;
    }
    return true;
}

/*
front(qoq):出队列,把一个用户数据从队列中拿出来(去掉队头)
@q:你要操作的队列的地址
返回值:
    返回true表示出队成功
    返回false表示出队失败
*/
bool DeQueue(LkQueue *q)
{
    if(QueueIsEmpty(q))
    {
        return false;
    }
    Node *p = q->front;
    if(q->front == q->rear)
    {
        q->front = q->rear = NULL;
    }
    else
    {
        q->front = p->next;
        q->front->prev = NULL;
        p->next = NULL;
    }
    free(p);
    q->num--;
    return true;
}